package wxdb.ui;

import java.util.*;
import java.io.*;

import wxdb.planner.*;
import wxdb.storage.StorageMgr;
public class Global {
	
	public static int STORAGE_PAGE_SIZE;
	public static int STORAGE_BUFFER_SIZE;
	public static int STORAGE_PREREAD_PAGE;
	public static int STORAGE_BITMAP_PAGE_COUNT;
	public static int STORAGE_CLEAN_COUNT;
	public static int STORAGE_BUF_CHECK;
	public static int UI_REGISTER_DBMAX;
	public static String VERSION;
	public static Management mg;
	
	public static boolean GROUP_BY = false;
	public static String group_by_field = "";
	public static boolean HAVING = false;
	public static boolean ORDER_BY = false;
	public static String order_by_field = "";
	
	public static boolean AVG = false;
	public static boolean SUM = false;
	public static boolean MIN = false;
	public static boolean MAX = false;
	public static boolean COUNT = false;
	public static String computefield = "";
	public static String asfield = "";
	
	public static int currentdb;
	public static boolean REFRESHTABLE = false;
	
	public static ArrayList queryResult = new ArrayList();
	public static ArrayList queryFields = new ArrayList();
	
	private static int dbCount = 0;
	private static HashMap<String,String> userMap = new HashMap<String, String>();
	public static int freeDBID = 0;
	public static HashMap<String,Integer> dbNameMap = new HashMap<String,Integer>();
	public static HashMap<Integer,String> dbIDMap = new HashMap<Integer, String>();

	private static Properties prop = new Properties();
	
	public Global(){
		try{
			FileInputStream fis = new FileInputStream("config/config.xml");
			prop.loadFromXML(fis);
			prop.list(System.out);
			initProp(prop);
			initDBID();
			initUser();
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
	
	public static int getDBCount(){
		return dbCount;
	}
	
	public static ArrayList<String> getUsers(){
		ArrayList<String> al = new ArrayList<String>();
		for (Iterator<String> iter = userMap.keySet().iterator(); iter.hasNext();) {
			String name = iter.next(); 
			al.add(name);
		}
		return al;
	}
	
	public static boolean isUserExist(String username){
		String data = userMap.get(username);
		if(data==null)
			return false;
		else
			return true;
	}
	
	public static StorageMgr storageMgr(){
		return new StorageMgr();
	}
	
	public static String getUserPasswd(String username){
		String data = userMap.get(username);
		String passwd = "";
		for(int i=0;i<data.length();i++){
			if(data.charAt(i)!=';'){
				passwd+=data.charAt(i);
			}else{
				break;
			}			
		}
		return passwd;
	}
	
	public static String[] getUserDatabases(String username){
		String data = userMap.get(username);
		String databases[] = new String[Global.UI_REGISTER_DBMAX];
		int length = 0;
		boolean first = true;
		int index = 0;
		String db = "";
		while(index < data.length()){	
			for(;index<data.length();index++){
				if(data.charAt(index)!=';'){
					db+=data.charAt(index);
				}else{
					if(first == false){
						databases[length] = new String(db);
						db = "";
						length++;
					}else{
						db = "";
						first = false;
						continue;
					}
				}			
			}
		}
		return databases;
	}
	
	public static void delUser(String name){
		try{
			int length = 0;
			String fileName = "config/user.txt";
			String data = "";
			RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
			long freadoff = randomFile.getFilePointer();
			long fwriteoff = randomFile.getFilePointer();
			while((data = randomFile.readLine())!=null){
				freadoff = randomFile.getFilePointer();
				String username = "";
				String userdata = "";
				int index=0;
				for(int i=0;i<data.length();i++){
					if(data.charAt(i)!=';'){
						username+=data.charAt(i);
					}else{
						index = i;
						break;
					}			
				}
				for(int i=index+1;i<data.length();i++)
					userdata += data.charAt(i);
				if(username.equals(name)){
					userMap.remove(username);
					while((data = randomFile.readLine())!=null){
						length = data.length();
						freadoff = randomFile.getFilePointer();
						randomFile.seek(fwriteoff);
						data+="\r\n";
						randomFile.writeBytes(data);
						fwriteoff = randomFile.getFilePointer();
						randomFile.seek(freadoff);				
					}
					randomFile.setLength(fwriteoff);
					break;
				}
				fwriteoff = randomFile.getFilePointer();
			}
			
			randomFile.close();
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
	
	public static void changeRights(String name, String dbs){
		try{
			long length = 0;
			String fileName = "config/user.txt";
			String data = "";
			RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
			long freadoff = randomFile.getFilePointer();
			long fwriteoff = randomFile.getFilePointer();
			while((data = randomFile.readLine())!=null){
				freadoff = randomFile.getFilePointer();
				String username = "";
				String userdata = "";
				int index=0;
				for(int i=0;i<data.length();i++){
					if(data.charAt(i)!=';'){
						username+=data.charAt(i);
					}else{
						index = i;
						break;
					}			
				}
				for(int i=index+1;i<data.length();i++)
					userdata += data.charAt(i);
				
				String pwd = "";
				index = 0;
				for(int i=0;i<userdata.length();i++){
					if(userdata.charAt(i)!=';'){
						pwd+=userdata.charAt(i);
					}else{
						index = i;
						break;
					}			
				}

				if(username.equals(name)){
					userMap.put(name, pwd+";"+dbs);
					
					String newdata = name+";"+pwd+";"+dbs+"\r\n";
					length = fwriteoff;
					String file = "config/tmp.txt";
					RandomAccessFile rf = new RandomAccessFile(file, "rw");
					rf.setLength(0);
					
					while((data = randomFile.readLine())!=null){
						data += "\r\n";
						rf.writeBytes(data);
					}
					rf.seek(0);
					
					randomFile.seek(fwriteoff);
					randomFile.writeBytes(newdata);
					
					length += newdata.length();
					while((data = rf.readLine())!=null){
						data+="\r\n";
						randomFile.writeBytes(data);
						length += data.length();
					}
					
					rf.setLength(0);
					rf.close();
					randomFile.setLength(length);
					break;
				}
				fwriteoff = randomFile.getFilePointer();
			}
			
			randomFile.close();
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
	
	public static void changePasswd(String name, String passwd){
		try{
			long length = 0;
			String fileName = "config/user.txt";
			String data = "";
			RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
			long freadoff = randomFile.getFilePointer();
			long fwriteoff = randomFile.getFilePointer();
			while((data = randomFile.readLine())!=null){
				freadoff = randomFile.getFilePointer();
				String username = "";
				String userdata = "";
				int index=0;
				for(int i=0;i<data.length();i++){
					if(data.charAt(i)!=';'){
						username+=data.charAt(i);
					}else{
						index = i;
						break;
					}			
				}
				for(int i=index+1;i<data.length();i++)
					userdata += data.charAt(i);
				
				String pwd = "";
				String dbs = "";
				index = 0;
				for(int i=0;i<userdata.length();i++){
					if(userdata.charAt(i)!=';'){
						pwd+=userdata.charAt(i);
					}else{
						index = i;
						break;
					}			
				}
				for(int i=index+1;i<userdata.length();i++)
					dbs += userdata.charAt(i);
				
				if(username.equals(name)){
					userMap.put(name, passwd+";"+dbs+";");
					
					String newdata = name+";"+passwd+";"+dbs+"\r\n";
					length = fwriteoff;
					String file = "config/tmp.txt";
					RandomAccessFile rf = new RandomAccessFile(file, "rw");
					rf.setLength(0);
					
					while((data = randomFile.readLine())!=null){
						data += "\r\n";
						rf.writeBytes(data);
					}
					rf.seek(0);
					
					randomFile.seek(fwriteoff);
					randomFile.writeBytes(newdata);
					
					length += newdata.length();
					while((data = rf.readLine())!=null){
						data+="\r\n";
						randomFile.writeBytes(data);
						length += data.length();
					}
					
					rf.setLength(0);
					rf.close();
					randomFile.setLength(length);
					break;
				}
				fwriteoff = randomFile.getFilePointer();
			}
			
			randomFile.close();
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
	
	public static void initUser(){
		try{
			String fileName = "config/user.txt";
			String data;
			RandomAccessFile randomFile = new RandomAccessFile(fileName, "r");
			while((data = randomFile.readLine())!=null){	
				String username = "";
				String userdata = "";
				int index=0;
				for(int i=0;i<data.length();i++){
					if(data.charAt(i)!=';'){
						username+=data.charAt(i);
					}else{
						index = i;
						break;
					}			
				}
				for(int i=index+1;i<data.length();i++)
					userdata += data.charAt(i);			
				userMap.put(username, userdata);
			}
			
			randomFile.close();
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
	
	/* initialize all the properties */
	public void initProp(Properties prop){
		STORAGE_PAGE_SIZE = Integer.parseInt(prop.getProperty("STORAGE_PAGE_SIZE"));
		STORAGE_BUFFER_SIZE = Integer.parseInt(prop.getProperty("STORAGE_BUFFER_SIZE"));
		STORAGE_PREREAD_PAGE = Integer.parseInt(prop.getProperty("STORAGE_PREREAD_PAGE"));
		STORAGE_BITMAP_PAGE_COUNT = Integer.parseInt(prop.getProperty("STORAGE_BITMAP_PAGE_COUNT"));
		STORAGE_BUF_CHECK = Integer.parseInt(prop.getProperty("STORAGE_BUF_CHECK"));
		STORAGE_CLEAN_COUNT = Integer.parseInt(prop.getProperty("STORAGE_CLEAN_COUNT"));
		UI_REGISTER_DBMAX = Integer.parseInt(prop.getProperty("UI_REGISTER_DBMAX"));
		VERSION = prop.getProperty("VERSION");
		//add more codes here
	}


	
	public void initDBID(){
		File file = new File("config/databases.txt");
		BufferedReader reader = null;
		try{
			reader = new BufferedReader(new FileReader(file));
			String dbName = null;
			Integer dbID = null;
			while((dbName = reader.readLine())!=null){
				dbID = new Integer(freeDBID);
				dbNameMap.put(dbName, dbID);
				dbIDMap.put(dbID, dbName);
				freeDBID++;
			}
			dbCount = freeDBID;
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
	
	/* set the name and value */
	public static void setNameValue(String name, String value){
		try{
			prop.setProperty(name, value);
		    FileOutputStream fos = new FileOutputStream("config/config.xml");
		    prop.storeToXML(fos, "wxdb");
		    fos.close();
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
	
	public static int getFreeDBID(){
		return freeDBID;
	}
	
	/* "" if not existed */
	public static String findDBName(int dbid){
		String dbName = dbIDMap.get(new Integer(dbid));
		if(dbName == null)
			return new String("");
		return dbName;
	}
	
	/* -1 if not existed */
	public static int findDBID(String dbName){
		Integer dbID = dbNameMap.get(dbName);
		if(dbID == null)
			return -1;
		int dbid = dbID.intValue();
		return dbid;
	}
	
	
	
    public static Planner planner() {
    	BasicQueryPlanner  qplanner = new BasicQueryPlanner();
        UpdatePlanner uplanner = new BasicUpdatePlanner();
        return new Planner(qplanner, uplanner);
    }
}
